package nku.csc364;

/**
 * 
 * Raj Akula
 * CSC 365 Assignment 5
 * 
 * his class extends the AbstractHashTable and implements Separate Chaining for its
 * hashing algorithm. The 'chains' used are the java.util.ArrayList class
 *
 */

import java.util.ArrayList;
import java.util.Iterator;

public class SeparateChainingHashTable extends AbstractHashTable {

	public SeparateChainingHashTable(int size, double loadFactor) {
		super(size, loadFactor);
	}

	/**
	 * Inserts into arraylist  based on the array index found
	 * by the hash function. If the key already exists
	 * in the arraylist the existing value is removed first, otherwise
	 * the value is added to the arraylist.
	 */
	public void insert(String key, Object data) {

		if (((ArrayList) (array[hash(key)])).contains(data)){
			((ArrayList) (array[hash(key)])).remove(data);
		}
		((ArrayList) (array[hash(key)])).add(data);
		
	}

	/**
	 * Based on the hash key loop through the array and return the
	 * value that matches the key.
	 */
	public Object find(String key) {
		int intKey = hash(key);
		Object retVal = null;

		
		boolean found=false;
		if (array[intKey] != null) {
			Iterator itr = ((ArrayList) (array[intKey])).iterator();
			while (!found && itr.hasNext()){
				Comparable next = (Comparable)itr.next();	
				if (next.compareTo(key)==0) {
					retVal = next;
					found=true;
				}
			}
		}

	
		return retVal;

	}
	
	/**
	 * 
	 * 
	 * Returns the index of the array where the arraylist for the values resides
	 */
	private int hash(String key) {

		
		int idx =binaryConcat(key) % array.length; 
		
		if (array[idx] == null) {
			array[idx] = new ArrayList();
		
		}
		return idx;
	}
	
	/**
	 * Based on the hash key loop through the arraylist bucket to find the
	 * value to delete if it exists
	 */
	public void delete(String key) {

		int initial = hash(key);
		Object retVal = null;

		int intKey = initial;

		Object obj = find(key);
		if (obj != null) {
			int idx = 0;
			boolean found=false;
			Iterator itr = ((ArrayList) (array[intKey])).iterator();
			while (!found && itr.hasNext()){
				Comparable next = (Comparable)itr.next();	
				if (next.compareTo(key)==0) {
					retVal = next;
					found=true;
				}else{
					idx++;
				}
				
			}
			
			if (found){
				((ArrayList) (array[intKey])).remove(idx);
			}

		}
		
		
	}
}
